package com.xxm.camera.camera2

import android.annotation.SuppressLint
import android.app.Application
import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CameraDevice
import android.hardware.camera2.CameraDevice.StateCallback
import android.hardware.camera2.CameraManager
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData

/**
 *Time:2023/6/13
 *Author:zhangwenshuan
 *Description:
 *since version
 *
 */
@SuppressLint("MissingPermission")
class Camera2Model(application: Application) : AndroidViewModel(application) {
    private val TAG = "Camera2Model"
    private val cameraMap = hashMapOf<String, NCameraInfo>()

    private var cameraManager: CameraManager? = null

     var handler = Handler(Looper.getMainLooper())

    val cameraInfo = MutableLiveData<List<NCameraInfo>>()

    var cameraCallback: CameraCallback? = null

    fun isSupportCamera(): Boolean {
        val cameraManager = getApplication<Application>().getSystemService(AppCompatActivity.CAMERA_SERVICE) as CameraManager
        return cameraManager.cameraIdList.isNotEmpty()
    }

    fun getCameraListInfo() {
        val cameraManager = getApplication<Application>().getSystemService(AppCompatActivity.CAMERA_SERVICE) as CameraManager
        if (cameraManager.cameraIdList.isNotEmpty()) {
            for (cameraId in cameraManager.cameraIdList) {
                val cameInfo = NCameraInfo()
                val characteristics = cameraManager.getCameraCharacteristics(cameraId)
                val facing = characteristics.get(CameraCharacteristics.LENS_FACING)

                cameInfo.id = cameraId
                cameInfo.face ="${ getFaceStr(facing)},CameraId:${cameraId}"
                Log.d(TAG, cameInfo.toString())
                cameraMap[cameraId] = cameInfo
            }
            cameraInfo.value = cameraMap.values.toList()
        }
    }

    fun openCamera(cameraId: String) {
        initCameraManager()
        cameraManager?.openCamera(cameraId, stateCallback, handler)
    }

    private fun initCameraManager() {
        if (cameraManager == null) {
            cameraManager = getApplication<Application>().getSystemService(AppCompatActivity.CAMERA_SERVICE) as CameraManager
        }
    }

    fun openAllCamera() {
        if (cameraMap.isEmpty()) getCameraListInfo()
        if (cameraMap.isEmpty()) Toast.makeText(getApplication(), "设备未检测到摄像", Toast.LENGTH_SHORT).show()
        cameraMap.values.forEach {
            openCamera(it.id)
        }
    }

    private fun getFaceStr(facing: Int?): String {
        if (facing != null) {
            return when (facing) {
                CameraCharacteristics.LENS_FACING_BACK -> "后置摄像头${facing}"
                CameraCharacteristics.LENS_FACING_FRONT -> "前置摄像头${facing}"
                CameraCharacteristics.LENS_FACING_EXTERNAL -> "扩展摄像头${facing}"
                else -> "未知摄像头:${facing}"
            }
        }
        return "无效摄像头"
    }

    fun closeCamera(nCameraInfo: NCameraInfo) {
        nCameraInfo.cameraDevice?.close()
        cameraMap[nCameraInfo.id]?.apply {
            state = 0
            cameraCallback?.onCameraClose(this)
        }
    }


    private val stateCallback=object : StateCallback() {
        override fun onOpened(camera: CameraDevice) {
            cameraMap[camera.id]?.apply {
                cameraDevice = camera
                state = 1
                cameraCallback?.onCameraOpen(this)
            }

        }

        override fun onDisconnected(camera: CameraDevice) {
            cameraMap[camera.id]?.apply {
                cameraDevice = camera
                state = 0
                cameraCallback?.onCameraClose(this)
            }
        }

        override fun onError(camera: CameraDevice, error: Int) {
            Log.e(TAG, "camera ${camera.id} error code:${error}")
            cameraMap[camera.id]?.apply {
                cameraDevice = camera
                state = 3
                cameraCallback?.onCameraError(this,error)
            }
        }
    }
}

interface CameraCallback {
    fun onCameraOpen(camera: NCameraInfo)

    fun onCameraClose(camera: NCameraInfo)

    fun onCameraError(camera: NCameraInfo, error: Int)
}